﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "CreatePlanViewDlg.h"
#include "ui_CreatePlanViewDlg.h"
#include "GmStyleSheetHelper.h"
#include "IDocument.h"
#include "LevelUtils.h"
#include "ElementId.h"
#include "BuildingUtils.h"
#include "ILevel.h"
#include "IBuilding.h"
#include "IGenericElement.h"
#include "IExternalObject.h"
#include <QVariant>

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"
using namespace gcmp;

#define QT_USER_ROLE Qt::UserRole

CreatePlanViewDlg::CreatePlanViewDlg(gcmp::IDocument* pDoc, QWidget *parent /*= 0*/)
    : QDialog(parent, Qt::FramelessWindowHint)
    , ui(NEW_AS_OWNER_PTR(Ui::CreatePlanViewDlg))
    , m_pDoc(pDoc)
{
    ui->setupUi(this);
    std::wstring styleSheetStr = GmStyleSheetHelper::Instance()->GetCurrentStyleData();
    setStyleSheet(QString::fromStdWString(styleSheetStr));
    ui->gbmp_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    ui->gbmp_title->setIconVisible(false);
    ui->gbmp_title->setMaxButtonVisible(false);
    ui->gbmp_title->setMinButtonVisible(false);
    ui->gbmp_title->setText(QString::fromStdWString(GBMP_TR(L"视图创建")));
    this->setProperty("use_gbmp_title", true);
    connect(ui->gbmp_title, &GmTitleBar::closeRequested, this, &CreatePlanViewDlg::reject);
    connect(ui->gbmp_title, &GmTitleBar::moveRequested, this, &CreatePlanViewDlg::onMoveRequested);

    connect(ui->okButton, SIGNAL(clicked()), this, SLOT(OKButtonPushed()));
    connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(CancelButtonPushed()));
    connect(ui->buildingLevelListTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(OnItemCheckBoxCheckStateChanged(QTreeWidgetItem *,int)));
}

CreatePlanViewDlg::~CreatePlanViewDlg()
{
}

std::vector<const gcmp::ILevel*> CreatePlanViewDlg::GetSelectedItemList() const
{
    std::vector<const gcmp::ILevel*> ret;
    int listCount = ui->buildingLevelListTreeWidget->topLevelItemCount();
    for (int i = 0; i < listCount; i++)
    {
        QTreeWidgetItem * storeyLevelListWidgetItem = ui->buildingLevelListTreeWidget->topLevelItem(i);
        int storeyLevelCount = storeyLevelListWidgetItem->childCount();

        for (int j = 0; j < storeyLevelCount; j++)
        {
            QTreeWidgetItem * storeyLevelWidgetItem = storeyLevelListWidgetItem->child(j);
            if (Qt::Checked == storeyLevelWidgetItem->checkState(0))
            {
                ElementId id = ElementId(storeyLevelWidgetItem->data(0, QT_USER_ROLE).toLongLong());
                IGenericElement *pOwnerElement = quick_cast<IGenericElement>(m_pDoc->GetElement(id));
                DBG_WARN_AND_CONTINUE_UNLESS(pOwnerElement, L"pOwnerElement为空",L"GDMPLab",L"2024-03-30");
                ILevel* pLevel = quick_cast<ILevel>(pOwnerElement->GetExternalObject());
                DBG_WARN_AND_CONTINUE_UNLESS(pLevel, L"pLevel为空",L"GDMPLab",L"2024-03-30");
                ret.push_back(pLevel);
            }
        }
    }
    return ret;
}

bool CreatePlanViewDlg::WhetherCreatePlanView() const
{
    return ui->planViewTypeCheckBox->isChecked();
}

//bool CreatePlanViewDlg::WhetherCreateCeilingView() const
//{
//    return ui->ceilingViewTypeCheckBox->isChecked();
//}

void CreatePlanViewDlg::InitDialog()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    //viewType
    ui->planViewTypeCheckBox->setCheckState(Qt::Checked);
    //ui->ceilingViewTypeCheckBox->setCheckState(Qt::Unchecked);

    //building and level List
    ui->buildingLevelListTreeWidget->clear();
    ui->buildingLevelListTreeWidget->setColumnCount(1);

    auto AddChildToTreeWidget = [](QTreeWidget *root,const std::wstring &childName, const std::vector<const ILevel*> &vecGrandson)
    {
        QTreeWidgetItem *childWidgetItem = new QTreeWidgetItem(root);
        childWidgetItem->setText(0, QString::fromStdWString(childName));
        childWidgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
        childWidgetItem->setCheckState(0, Qt::Unchecked);

        FOR_EACH(grandson, vecGrandson)
        {
            QTreeWidgetItem *grandsonWidgetItem = new QTreeWidgetItem(childWidgetItem);
            grandsonWidgetItem->setText(0, QString::fromStdWString(grandson->GetName()));
            grandsonWidgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
            grandsonWidgetItem->setCheckState(0, Qt::Unchecked);

            const IElement* pOwnerElement = grandson->GetOwnerElement();
            DBG_WARN_AND_CONTINUE_UNLESS(pOwnerElement, L"pOwnerElement为空",L"GDMPLab",L"2024-03-30");
            grandsonWidgetItem->setData(0, QT_USER_ROLE, QVariant(pOwnerElement->GetElementId().AsInt64()));
        }
    };

    //单体
    {
        //将楼层按单体分类
        std::vector<const gcmp::ILevel*> vecAllStorey = LevelUtils::GetStoreyLevelsFromLowToHigh(m_pDoc);
        std::vector<std::vector<const ILevel*>> tmpBuildings;
        std::vector<const ILevel*> preBuilding;
        gcmp::ElementId preBuildingId = ElementId::InvalidID;
        FOR_EACH(pStorey, vecAllStorey)
        {
            if (!pStorey)
                continue;

            const gcmp::ElementId currentBuildingId = pStorey->GetBuildingId();
            if (currentBuildingId == preBuildingId)
            {
                preBuilding.push_back(pStorey);
            }
            else
            {
                if (!preBuilding.empty())
                {
                    tmpBuildings.push_back(preBuilding);
                }
                preBuilding.clear();
                preBuilding.push_back(pStorey);
            }
            preBuildingId = currentBuildingId;
        }
        tmpBuildings.push_back(preBuilding);

        //添加到Tree中
        FOR_EACH(building, tmpBuildings)
        {
            ElementId buildingId = building.front()->GetBuildingId();
            IBuilding *pBuilding = BuildingUtils::GetBuildingById(m_pDoc, buildingId);
            DBG_WARN_AND_CONTINUE_UNLESS(pBuilding, L"pBuilding为空",L"GDMPLab",L"2024-03-30");
            std::wstring buildingName = pBuilding->GetName();
            AddChildToTreeWidget(ui->buildingLevelListTreeWidget, buildingName, building);
        }
    }

    //参照标高(目前只有一种标高)
    {
        std::vector<const gcmp::ILevel*> vecAllILevel = LevelUtils::GetReferenceLevelsFromLowToHigh(m_pDoc);
        if (!vecAllILevel.empty())
        {
            std::wstring levelsName = std::wstring(L"参照标高");
            AddChildToTreeWidget(ui->buildingLevelListTreeWidget, levelsName, vecAllILevel);
        }
    }

    ui->buildingLevelListTreeWidget->show();
}

void CreatePlanViewDlg::onMoveRequested(const QPoint& cursorPos, const QPoint& offset)
{
    Q_UNUSED(cursorPos);
    move(pos() + offset);
}

void CreatePlanViewDlg::OKButtonPushed()
{
    QDialog::accept();
}

void CreatePlanViewDlg::CancelButtonPushed()
{
    QDialog::reject();
}

void CreatePlanViewDlg::OnItemCheckBoxCheckStateChanged(QTreeWidgetItem *item, int col)
{
    Qt::CheckState state = item->checkState(0);
    int childCount = item->childCount();
    //叶子节点
    if (0 == childCount)
    {
        QTreeWidgetItem *pParent = item->parent();
        const int parentChildCount = pParent->childCount();
        int ParentChildCheckedCount = 0;
        for (int i = 0; i < parentChildCount;i++)
        {
            if (Qt::Checked == pParent->child(i)->checkState(0))
            {
                ParentChildCheckedCount++;
            }
        }

        if (parentChildCount == ParentChildCheckedCount)
        {
            pParent->setCheckState(0, Qt::Checked);
        }
        else if(0==ParentChildCheckedCount)
        {
            pParent->setCheckState(0, Qt::Unchecked);
        }
        else
        {
            pParent->setCheckState(0, Qt::PartiallyChecked);
        }
    }
    else          //非叶子节点
    {
        for (int i = 0; i < childCount; i++)
        {
            item->child(i)->setCheckState(0, state);
        }
    }
}
